package com.arpa.ntocc.basic.api.mapper;

import com.arpa.ntocc.basic.api.domain.entity.TableBackupConfig;
import com.arpa.ntocc.basic.api.domain.dto.TableBackupConfigDTO;
import com.arpa.ntocc.basic.api.domain.vo.TableBackupConfigVO;
import com.baomidou.mybatisplus.annotation.SqlParser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 表数据备份配置 Mapper 接口
 * </p>
 *
 * @author LEO
 * @since 2021-06-08
 */
public interface TableBackupConfigMapper extends BaseMapper<TableBackupConfig> {

    /**
     * 查询列表
     *
     * @param tableBackupConfigDTO
     * @return
     */
    List<TableBackupConfigVO> queryList(TableBackupConfigDTO tableBackupConfigDTO);

    /**
     * 查询合计,包含总数
     *
     * @param tableBackupConfigDTO
     * @return
     */
    TableBackupConfigVO queryListSum(TableBackupConfigDTO tableBackupConfigDTO);

    /**
     * 校验主库表是否存在
     * SqlParser(filter = true) 表示过滤SQL解析，即不会进入ISqlParser解析链，否则会报错：
     * Failed to process, please exclude the tableName or statementId.
     *
     * @param tableName 表名
     * @return 表名
     */
    @SqlParser(filter = true)
    @Select("SHOW TABLES LIKE #{tableName};")
    String queryTableIsExistInMaster(String tableName);

    /**
     * 校验从库表是否存在
     *
     * @param tableName 表名
     * @return 表名
     */
    @SqlParser(filter = true)
    @Select("SHOW TABLES LIKE #{tableName};")
    String queryTableIsExistInSlave(String tableName);

    /**
     * 查询主库表数据结构
     * 在传入[表名]作为参数时，要使用${tableName}的格式
     *
     * @param tableName 表名
     * @return 表结构
     */
    @SqlParser(filter = true)
    @Select("SHOW CREATE TABLE ${tableName};")
    Map<String, String> queryTableStructureInMaster(@Param(value = "tableName") String tableName);

    /**
     * 在从库创建表
     *
     * @param tableStructure 表结构sql
     */
    @SqlParser(filter = true)
    @Update("${tableStructure}")
    void createTableInSlave(@Param(value = "tableStructure") String tableStructure);

    /**
     * 查询主库表列字段
     *
     * @param tableName 表名
     * @return 列字段
     */
    @SqlParser(filter = true)
    @Select("SHOW COLUMNS FROM ${tableName};")
    List<Map<String, String>> queryTableFieldDataInMaster(@Param(value = "tableName") String tableName);

    /**
     * 查询主库表数据
     * 备注：为什么不是直接 SELECT * FROM tableName ? 因为当字段值为null时，最终查到的map里没有此字段。
     *
     * @param tableName       表名
     * @param tableColumnData 查询的列字段
     * @param time            查询此时间之前的所有数据
     * @param limitCount      查询的数据条数
     * @return 表数据
     */
    @SqlParser(filter = true)
    @Select("SELECT ${tableColumnData} FROM ${tableName} WHERE gmt_created <= #{time} ORDER BY id LIMIT #{limitCount};")
    List<Map<String, String>> queryTableDataInMaster(@Param(value = "tableName") String tableName, @Param(value = "tableColumnData") String tableColumnData, String time, Integer limitCount);



    /**
     * 查询主库表数据 (指定起始时间)
     * 备注：为什么不是直接 SELECT * FROM tableName ? 因为当字段值为null时，最终查到的map里没有此字段。
     *
     * @param tableName       表名
     * @param tableColumnData 查询的列字段
     * @param time            查询此时间之前的所有数据
     * @param limitCount      查询的数据条数
     * @return 表数据
     */
    @SqlParser(filter = true)
    @Select("SELECT ${tableColumnData} FROM ${tableName} WHERE date(gmt_created) <= #{appointedDay} AND date(gmt_created) <= #{time} ORDER BY id LIMIT #{limitCount};")
    List<Map<String, String>> queryAppointedDay(@Param(value = "tableName") String tableName, @Param(value = "tableColumnData") String tableColumnData, String appointedDay, String time, Integer limitCount);

    /**
     * 查询主库表数据条数
     *
     * @param tableName 表名
     * @param time      查询此时间之前的所有数据
     * @return 表数据
     */
    @SqlParser(filter = true)
    @Select("SELECT COUNT(1) FROM ${tableName} WHERE gmt_created <= #{time};")
    long countTableDataInMaster(@Param(value = "tableName") String tableName, String time);

    /**
     * 查询主库表数据条数 (指定起始时间)
     *
     * @param tableName 表名
     * @param time      查询此时间之前的所有数据
     * @return 表数据
     */
    @SqlParser(filter = true)
    @Select("SELECT COUNT(1) FROM ${tableName} WHERE date(gmt_created) <= #{appointedDay} AND date(gmt_created) <= #{time};")
    long countAppointedDay(@Param(value = "tableName") String tableName, String appointedDay, String time);

    /**
     * 插入数据到从库
     *
     * @param tableName  表名
     * @param columnData 列结构
     * @param tableData  数据
     * @return 插入成功数量
     */
    @SqlParser(filter = true)
    long insertTableDataInSlave(@Param(value = "tableName") String tableName, @Param(value = "columnData") String columnData, List<Map<String, String>> tableData);

    /**
     * 删除主库表数据
     *
     * @param tableName 表名
     * @param time      删除此时间之前的所有数据
     * @return 删除成功数量
     */
    @SqlParser(filter = true)
    @Update("DELETE FROM ${tableName} WHERE gmt_created <= #{time} ORDER BY id LIMIT #{limitCount};")
    long deleteTableDataInMaster(@Param(value = "tableName") String tableName, String time, Integer limitCount);

    /**
     * 删除主库表数据 (指定起始时间)
     *
     * @param tableName 表名
     * @param time      删除此时间之前的所有数据
     * @return 删除成功数量
     */
    @SqlParser(filter = true)
    @Update("DELETE FROM ${tableName} WHERE date(gmt_created) <= #{appointedDay} AND date(gmt_created) <= #{time} ORDER BY id LIMIT #{limitCount};")
    long deleteAppointedDay(@Param(value = "tableName") String tableName, String appointedDay, String time, Integer limitCount);
}
